package org.example.commerce.imp.service.impl;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.example.commerce.api.beans.OrderInfo;
import org.example.commerce.api.beans.OrderItemInfo;
import org.example.commerce.api.beans.OrderParam;
import org.example.commerce.api.beans.SelectOrderParam;
import org.example.commerce.dao.OrderItemMapper;
import org.example.commerce.dao.OrderMapper;
import org.example.commerce.dao.entity.Goods;
import org.example.commerce.dao.entity.Order;
import org.example.commerce.dao.entity.OrderItem;
import org.example.commerce.dao.vo.OrderItemVo;
import org.example.commerce.dao.vo.OrderVo;
import org.example.commerce.imp.service.GoodsService;
import org.example.commerce.imp.service.OrderService;
import org.example.common.response.R;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service
@Slf4j
public class OrderServiceImpl implements OrderService  {

    @Autowired
    GoodsService goodsService;

    @Autowired
    OrderMapper orderMapper;

    @Autowired
    OrderItemMapper orderItemMapper;
    @Override
    public String generatecode() {
        Snowflake snowflake = IdUtil.getSnowflake();
        return snowflake.nextIdStr();
    }

    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public R<OrderInfo> createOrder(OrderParam request) {
        //生成订单code
        String orderCode = generatecode();
        log.info("add Order code = {}", orderCode);
        // 1.1.1 ids
        // 取出所有id
        List<Long> ids = request.getItems().stream()
                .map(item -> item.getId())
                .collect(Collectors.toList());
        // 1.1.2 quantity
        // 取出所有商品数量
        List<Integer> quantity = request.getItems().stream()
                .map(item -> item.getQuantity())
                .collect(Collectors.toList());
        // 1.2 goods
        // 通过id查询出所有drink
        List<Goods> goods = goodsService.loadGoods(ids);

        // 1.3，items
        // 每一行单品价格
        Map<Integer,BigDecimal> items  = new HashMap<>();
        for (int i = 0; i < ids.size(); i++) {
            items.put(quantity.get(i), goods.get(i).getPrice());
        }
        // 1.3 totals
        // 计算出价格总和
        BigDecimal total = BigDecimal.ZERO;
        for(Map.Entry<Integer, BigDecimal> entry: items.entrySet()){
            total= total.add(entry.getValue().multiply(BigDecimal.valueOf(entry.getKey())));
        }
        //1.4 订单表插入
        orderMapper.insert(
             Order.builder()
                        .code(orderCode)
                        .createTime(LocalDateTime.now())
                        .customer(request.getCustomer())
                        .total(total)
                        .status(0).build()
        );
        //2.1订单详情表插入
        List<OrderItemInfo> orderItemInfos =new ArrayList<>();
        for (int i = 0; i < ids.size(); i++) {
            orderItemMapper.insert(
                    OrderItem.builder()
                            .orderId(orderCode)
                            .itemsId(ids.get(i))
                            .itemsPrice(goods.get(i).getPrice())
                            .itemsQuantity(quantity.get(i))
                            .itemsTotal(goods.get(i).getPrice().multiply(BigDecimal.valueOf(quantity.get(i))))
                            .build()
            );

            orderItemInfos.add(
                    OrderItemInfo.builder()
                            .id(ids.get(i))
                            .price(goods.get(i).getPrice())
                            .number(quantity.get(i))
                            .itemTotal(goods.get(i).getPrice().multiply(BigDecimal.valueOf(quantity.get(i))))
                            .build()
            );
        }
        return R.success(
                OrderInfo.builder()
                        .id(orderCode)
                        .customer(request.getCustomer())
                        .createTime(LocalDateTime.now())
                        .total(total)
                        .status(0)
                        .items(orderItemInfos)
                        .build()
        );
    }

    @Override
    public R<List<OrderVo>> selectOrder(SelectOrderParam request) {
        //订单表查询
        Example example = new Example(Order.class);
        example.createCriteria()
                .orEqualTo("id",request.getId())
                .orEqualTo("code",request.getCode())
                .orLike("createTime","*"+request.getCreateTime()+"*")
                .orEqualTo("customer",request.getCustomer());
        List<Order> orders = orderMapper.selectByExample(example);
        List<OrderVo> orderVoList = new ArrayList();
        //订单详情表查询
        for(Order order : orders){
            List<OrderItemVo> orderItemVos = orderItemMapper.selectByOrderId(order.getCode());
            OrderVo orderVo = new OrderVo();
            BeanUtils.copyProperties(order,orderVo);
            orderVo.setItems(orderItemVos);
            orderVoList.add(orderVo);
        }
        return R.success(orderVoList);
    }

    @Override
    public PageInfo<Order> selectAllOrder(Integer page, Integer pageSize) {
        PageHelper.startPage(page,pageSize);
        List<Order> orders = orderMapper.selectAll();
        PageInfo<Order> result = new PageInfo<>(orders);
        return  result;
    }

    @Override
    public R<String> deleteOrderByCode(String code) {
        Example example = new Example(Order.class);
        example.createCriteria().andEqualTo("code",code);
        orderMapper.deleteByExample(example);

        Example iexample = new Example(OrderItem.class);
        iexample.createCriteria().andEqualTo("orderId",code);
        orderItemMapper.deleteByExample(iexample);
        return R.success("删除成功");
    }


}
